
from typing import Dict, List, Optional, Any
from .config_manager import ConfigManager, get_config_manager
from .protocol_factory import ProtocolFactory
from .communication_interface import CommunicationInterface
from ..utils.logger import get_logger

# 添加日志记录器
logger = get_logger("driver.core")

class CommunicationManager:
    """通信管理器，用于管理多个通信实例（单例模式）"""

    _instance = None
    _initialized = False

    def __new__(cls, config_manager: Optional[ConfigManager] = None, config_file: Optional[str] = None):
        """
        实现单例模式
        """
        if cls._instance is None:
            cls._instance = super(CommunicationManager, cls).__new__(cls)
        return cls._instance

    def __init__(self, config_manager: Optional[ConfigManager] = None, config_file: Optional[str] = None):
        """
        初始化通信管理器

        Args:
            config_manager: 配置管理器实例（可选）
            config_file: 用户配置文件路径（可选）
        """
        # 防止重复初始化
        if CommunicationManager._initialized:
            return

        try:
            if config_manager:
                self.config_manager = config_manager
            else:
                # 如果没有提供配置管理器，则创建一个新的
                self.config_manager = get_config_manager(config_file)

            self.communications: Dict[str, CommunicationInterface] = {}
            self.communication_configs: Dict[str, Dict[str, Any]] = {}

            CommunicationManager._initialized = True
        except Exception as e:
            logger.error(f"CommunicationManager initialization failed: {e}")
            raise

    def load_communications(self, protocols: Optional[List[str]] = None) -> None:
        """
        加载通信配置并创建通信实例

        Args:
            protocols: 要加载的协议列表，如果为None则加载所有协议
        """
        try:
            if protocols is None:
                # 获取所有协议
                protocols = list(self.config_manager.get("devices", {}).keys())

            for protocol in protocols:
                devices_config = self.config_manager.get_devices_config(protocol)
                for device_config in devices_config:
                    device_id = device_config.get("device_id")
                    if not device_id:
                        logger.warning(f"Device config missing device_id for protocol {protocol}")
                        continue

                    try:
                        # 创建通信实例
                        communication = ProtocolFactory.create_protocol(protocol, device_config)
                        # 存储通信实例和配置
                        self.communications[device_id] = communication
                        self.communication_configs[device_id] = device_config
                        logger.info(f"Communication {device_id} loaded for protocol {protocol}")
                    except Exception as e:
                        logger.error(f"Failed to create communication {device_id} for protocol {protocol}: {e}")
        except Exception as e:
            logger.error(f"Error loading communications: {e}")
            raise

    def get_communication(self, device_id: str) -> Optional[CommunicationInterface]:
        """
        获取通信实例

        Args:
            device_id: 设备ID

        Returns:
            CommunicationInterface: 通信实例，如果未找到则返回None
        """
        return self.communications.get(device_id)

    def add_communication(self, device_id: str, communication: CommunicationInterface, config: Dict[str, Any]) -> bool:
        """
        添加通信实例

        Args:
            device_id: 设备ID
            communication: 通信实例
            config: 通信配置

        Returns:
            bool: 是否添加成功
        """
        try:
            if device_id in self.communications:
                logger.warning(f"Communication {device_id} already exists")
                return False

            self.communications[device_id] = communication
            self.communication_configs[device_id] = config
            logger.info(f"Communication {device_id} added")
            return True
        except Exception as e:
            logger.error(f"Error adding communication {device_id}: {e}")
            return False

    def remove_communication(self, device_id: str) -> bool:
        """
        移除通信实例

        Args:
            device_id: 设备ID

        Returns:
            bool: 是否移除成功
        """
        try:
            if device_id not in self.communications:
                logger.warning(f"Communication {device_id} not found")
                return False

            # 断开通信连接
            communication = self.communications[device_id]
            try:
                if communication.is_connected:
                    communication.disconnect()
            except Exception as e:
                logger.error(f"Error disconnecting communication {device_id}: {e}")

            # 移除通信
            del self.communications[device_id]
            del self.communication_configs[device_id]
            logger.info(f"Communication {device_id} removed")
            return True
        except Exception as e:
            logger.error(f"Error removing communication {device_id}: {e}")
            return False

    def connect_communication(self, device_id: str) -> bool:
        """
        连接通信

        Args:
            device_id: 设备ID

        Returns:
            bool: 是否连接成功
        """
        try:
            communication = self.communications.get(device_id)
            if not communication:
                logger.error(f"Communication {device_id} not found")
                return False

            result = communication.connect()
            if result:
                logger.info(f"Communication {device_id} connected")
            else:
                logger.warning(f"Communication {device_id} connection failed")
            return result
        except Exception as e:
            logger.error(f"Error connecting communication {device_id}: {e}")
            return False

    def disconnect_communication(self, device_id: str) -> bool:
        """
        断开通信

        Args:
            device_id: 设备ID

        Returns:
            bool: 是否断开成功
        """
        try:
            communication = self.communications.get(device_id)
            if not communication:
                logger.error(f"Communication {device_id} not found")
                return False

            result = communication.disconnect()
            if result:
                logger.info(f"Communication {device_id} disconnected")
            else:
                logger.warning(f"Communication {device_id} disconnection failed")
            return result
        except Exception as e:
            logger.error(f"Error disconnecting communication {device_id}: {e}")
            return False

    def get_all_communications(self) -> Dict[str, CommunicationInterface]:
        """
        获取所有通信实例

        Returns:
            Dict[str, CommunicationInterface]: 包含所有通信实例的字典副本
        """
        return self.communications.copy()

    def get_communication_config(self, device_id: str) -> Optional[Dict[str, Any]]:
        """
        获取通信配置

        Args:
            device_id: 设备ID

        Returns:
            Dict[str, Any]: 对应的通信配置字典，如果未找到则返回None
        """
        return self.communication_configs.get(device_id)

    def initialize_communication(self, device_id: str, auto_connect: bool = True, init_params: Optional[Dict[str, Any]] = None) -> bool:
        """
        初始化通信，包括连接和基本内容初始化

        Args:
            device_id: 设备ID
            auto_connect: 是否自动连接通信
            init_params: 初始化参数，用于通信的基本内容初始化

        Returns:
            bool: 是否初始化成功
        """
        try:
            communication = self.communications.get(device_id)
            if not communication:
                logger.error(f"Communication {device_id} not found")
                return False

            # 如果需要自动连接且通信未连接，则连接通信
            if auto_connect and not communication.is_connected:
                if not self.connect_communication(device_id):
                    logger.error(f"Failed to connect communication {device_id} during initialization")
                    return False

            # 执行通信基本内容初始化
            # 这里可以调用通信的初始化方法（如果通信实现了初始化接口）
            if hasattr(communication, 'initialize') and callable(getattr(communication, 'initialize')):
                init_result = communication.initialize(init_params or {})
                if not init_result:
                    logger.warning(f"Communication {device_id} initialization returned False")
            else:
                # 如果通信没有专门的初始化方法，则使用通用初始化逻辑
                logger.info(f"Communication {device_id} has no specific initialize method, using generic initialization")
                # 可以在这里添加通用的初始化逻辑

            logger.info(f"Communication {device_id} initialized successfully")
            return True
        except Exception as e:
            logger.error(f"Error initializing communication {device_id}: {e}")
            return False

    def initialize_all_communications(self, auto_connect: bool = True, init_params: Optional[Dict[str, Any]] = None) -> Dict[str, bool]:
        """
        初始化所有通信

        Args:
            auto_connect: 是否自动连接通信
            init_params: 初始化参数，用于通信的基本内容初始化

        Returns:
            Dict[str, bool]: 每个通信的初始化结果
        """
        results = {}
        for device_id in self.communications:
            results[device_id] = self.initialize_communication(device_id, auto_connect, init_params)
        return results


def get_communication_manager(config_manager: Optional[ConfigManager] = None,
                              config_file: Optional[str] = None) -> "CommunicationManager":
    """
    获取通信管理器实例（全局访问点）

    Args:
        config_manager: 配置管理器实例（可选）
        config_file: 配置文件路径（可选）

    Returns:
        CommunicationManager: 通信管理器实例
    """
    return CommunicationManager(config_manager, config_file)